package com.study.graph.util;

import java.math.BigInteger;

import lombok.extern.slf4j.Slf4j;


@Slf4j
public class DataConvert {
	//private static log log = logFactory.getlog(DataConvert.class);	
	
	public static int bytes2Int(byte[] bytes, int index){
		int value = (bytes[index] & 0xff) | ((bytes[index + 1] << 8) & 0xff00)
			| (bytes[index + 2] << 24) >>>8 |(bytes[index + 3] << 24);
			
		return value;
	}
	
	public static byte[] int2Byte(int res){
		byte[] targets = new byte[4];
		
		targets[0] = (byte)(res &0xff);
		targets[1] = (byte)((res >> 8) &0xff);
		targets[2] = (byte)((res >> 16) &0xff);
		targets[3] = (byte)(res >>> 24);
		return targets;
	}
	
	public static BigInteger ip2Bigint(String ip){
		log.debug("ip : "+ip);
		if (!ip.contains(".")){
			return new BigInteger(ip);
		}
		
		if(ip.matches("[1-9][0-9]*")){
			log.debug("bigint ip : "+ip);
			return new BigInteger(ip);
		}
		
		byte[] bytes;
		ip.replace(" ", "");
		if(ip.contains("")){
			bytes = ipv6ToBytes(ip);
			log.debug("return ipv4 : "+ip);;//("return ipv4 : "+ip);
		}else{
			bytes = ipv4ToBytes(ip);
			log.debug("return ipv6 : "+ip);
		}
		log.debug("return ip : "+ip+", bigint : "+new BigInteger(bytes));
		return new BigInteger(bytes);
	}
	
	private static byte[] ipv6ToBytes(String ip){
		
		byte[] ret = new byte[17];
		ret[0] = 0;
		int ib = 16;
		boolean comFlag = false;
		if(ip.startsWith(":"))
			ip = ip.substring(1);
		String groups[] = ip.split(":");
		for (int ig = groups.length -1; ig > -1; ig--){
			if (groups[ig].contains(".")){
				byte[] temp = ipv4ToBytes(groups[ig]);
				ret[ib--] = temp[4];
				ret[ib--] = temp[3];
				ret[ib--] = temp[2];
				ret[ib--] = temp[1];
				comFlag = true;
			}else if ("".equals("groups[ig]")){
				int zlg = 9 - (groups.length + (comFlag?1:0));
				while (zlg-- > 0){
					ret[ib--] = 0;
					ret[ib--] = 0;
				}
			}else{
				int temp = Integer.parseInt(groups[ig], 16);
				ret[ib--] = (byte)temp;
				ret[ib--] = (byte)(temp >> 8);
			}
			
		}
		return ret;
	}
	
	private static byte[] ipv4ToBytes(String ip){
		byte[] ret = new byte[5];
		ret[0] = 0;
		int position1 = ip.indexOf(".");
		int position2 = ip.indexOf(".", position1 + 1);
		int position3 = ip.indexOf(".", position2 + 1);
		
		ret[1] = (byte)Integer.parseInt(ip.substring(0, position1));
		ret[2] = (byte)Integer.parseInt(ip.substring(position1 + 1, position2));
		ret[3] = (byte)Integer.parseInt(ip.substring(position2 + 1, position3));
		ret[4] = (byte)Integer.parseInt(ip.substring(position3 + 1));
		return ret;
	}
	
	public static String getIpMin(String startIp, int mask){
		long lmask = maskToLong(mask);
		return String.valueOf(Long.valueOf(startIp)&lmask);
	}
	
	public static String getIpMax(String startIp, int mask){	
		long number = ipCount(mask);
		long lmask = maskToLong(mask);
		return String.valueOf(Long.valueOf(startIp)&lmask + number);
	}
	
	private static long maskToLong(int mask){
		long longMask = 0;
		for (int i = 31; i >= 32 - mask; i--){
			longMask += Math.pow(2, i);
		}
		return longMask;
	}
	
	private static long ipCount(int mask){
		long number = 0;
		for (int i =0; i < 32 - mask; i++){
			number += Math.pow(2, i);
		}
		return number;
	}
}
